package com.gombe.credit.app.request

import android.os.Handler
import android.os.Looper
import com.gombe.credit.app.GombeCreditApp
import com.gombe.credit.app.common.CommonActivity
import com.gombe.credit.app.event.GombeCreditEventData
import com.gombe.credit.app.ui.dialog.DialogGombeCreditReload
import com.gombe.credit.app.utils.log.GombeCreditLogger
import org.json.JSONObject
import java.lang.ref.WeakReference

/**
 * 全局网络错误管理类
 */
object NetworkErrorManager {
    private var isShowingDialog = false

    // 存储待重试的请求队列（按照添加顺序）
    private val retryQueue = LinkedHashMap<String, RetryRequest>()

    // 当前显示的对话框
    private var currentDialog: DialogGombeCreditReload? = null

    // 注册的 Activity 引用（弱引用避免内存泄漏）
    private val registeredActivities = mutableSetOf<WeakReference<CommonActivity>>()

    // 当前可用的 Context（从注册的 Activity 中获取）
    private val availableContext: CommonActivity?
        get() = getLatestActivity()

    // 重试请求数据类
    data class RetryRequest(
        val requestId: String = generateRequestId(),
        val requestType: String, // "POST", "UPLOAD" 等
        val url: String,
        val params: Any?, // 可以是 JSONObject, Map 等
        val headers: Map<String, String>?,
        val originalCallback: IHttpCallback,
        val timestamp: Long = System.currentTimeMillis(),
        var retryCount: Int = 0
    ) {
        companion object {
            fun generateRequestId(): String {
                return "req_${System.currentTimeMillis()}_${(0..1000).random()}"
            }
        }
    }

    /**
     * 注册 Activity（在 CommonActivity onCreate 中调用）
     */
    fun registerActivity(activity: CommonActivity) {
        synchronized(registeredActivities) {
            // 清理已销毁的 Activity 引用
            registeredActivities.removeAll { it.get() == null }
            // 添加新的 Activity 引用
            registeredActivities.add(WeakReference(activity))
        }
        GombeCreditLogger.d("register Activity: ${activity::class.java.simpleName}")
    }

    /**
     * 取消注册 Activity（在 CommonActivity onDestroy 中调用）
     */
    fun unregisterActivity(activity: CommonActivity) {
        synchronized(registeredActivities) {
            registeredActivities.removeAll { it.get() == activity || it.get() == null }
        }
        GombeCreditLogger.d("unregister Activity: ${activity::class.java.simpleName}")

        // 如果当前显示的对话框属于正在销毁的 Activity，关闭对话框
        if (getLatestActivity() == null && isShowingDialog) {
            resetState()
        }
    }

    /**
     * 获取最新的 Activity（用于显示 Dialog）
     */
    private fun getLatestActivity(): CommonActivity? {
        synchronized(registeredActivities) {
            // 清理已销毁的 Activity 引用
            registeredActivities.removeAll { it.get() == null }
            // 返回最后一个注册的 Activity（通常是最顶层的）
            return registeredActivities.lastOrNull()?.get()
        }
    }

    /**
     * 处理网络错误，决定是否显示全局Dialog
     */
    fun handleNetworkError(error: OkHttpUtil.NetworkError?, requestData: RetryRequest? = null) {
        GombeCreditApp.app.publisher.publish(GombeCreditEventData(GombeCreditEventData.TYPE.GOMBECREDIT_NET_ERROR))
        // 检查是否应该显示错误提示
        if (!shouldShowErrorDialog(error)) {
            return
        }

        // 如果有请求数据，添加到重试队列
        requestData?.let { request ->
            addToRetryQueue(request)
        }

        // 防止频繁弹窗
        if (isShowingDialog) {
            return
        }

        // 获取可用的 Context 并显示对话框
        val context = availableContext
        if (context != null) {
            showGlobalErrorDialog(context, error)
        } else {
            GombeCreditLogger.w("No Context available, unable to display network error dialog box")
        }
    }

    /**
     * 添加请求到重试队列
     */
    private fun addToRetryQueue(request: RetryRequest) {
        synchronized(retryQueue) {
            // 检查是否已存在相同的请求（基于URL和参数）
            val existingKey = findExistingRequestKey(request)
            if (existingKey != null) {
                // 更新已有的请求
                retryQueue[existingKey] = request
            } else {
                // 添加新请求
                retryQueue[request.requestId] = request
            }
        }
        GombeCreditLogger.d("Add to retry queue, current queue size: ${retryQueue.size}")
    }

    /**
     * 查找已存在的请求Key（防止重复添加）
     */
    private fun findExistingRequestKey(newRequest: RetryRequest): String? {
        return retryQueue.entries.firstOrNull { entry ->
            val existing = entry.value
            existing.url == newRequest.url &&
                    existing.requestType == newRequest.requestType &&
                    areParamsEqual(existing.params, newRequest.params)
        }?.key
    }

    /**
     * 比较参数是否相等
     */
    private fun areParamsEqual(params1: Any?, params2: Any?): Boolean {
        if (params1 == null && params2 == null) return true
        if (params1 == null || params2 == null) return false
        return params1.toString() == params2.toString()
    }

    /**
     * 判断是否应该显示全局错误对话框
     */
    fun shouldShowErrorDialog(error: OkHttpUtil.NetworkError?): Boolean {
        return when (error?.type) {
            OkHttpUtil.NetworkErrorType.TIMEOUT -> true
            OkHttpUtil.NetworkErrorType.NETWORK_UNAVAILABLE -> true
            OkHttpUtil.NetworkErrorType.HOST_NOT_FOUND -> true
            OkHttpUtil.NetworkErrorType.CONNECTION_REFUSED -> true
            else -> false
        }
    }

    /**
     * 显示全局错误对话框
     */
    private fun showGlobalErrorDialog(activity: CommonActivity, error: OkHttpUtil.NetworkError?) {
        // 确保在主线程显示对话框
        if (Looper.myLooper() != Looper.getMainLooper()) {
            Handler(Looper.getMainLooper()).post {
                showGlobalErrorDialog(activity, error)
            }
            return
        }
        isShowingDialog = true
        try {
            currentDialog = activity.showGombeCreditGlobalErrorDialog(
                onReloadClick = {
                    //重试
                    executeRetryQueue()
                },
                onDismissListener = {
                    isShowingDialog = false
                    currentDialog = null
                })
        } catch (e: Exception) {
            GombeCreditLogger.e("Failed to display network error dialog box: ${e.message}")
            isShowingDialog = false
            currentDialog = null
        }
    }

    /**
     * 执行重试队列（按照添加顺序）
     */
    private fun executeRetryQueue() {
        if (retryQueue.isEmpty()) {
            GombeCreditLogger.d("The retry queue is empty")
            return
        }

        // 复制队列并清空原队列（防止重试过程中新请求加入造成混乱）
        val queueToRetry = synchronized(retryQueue) {
            LinkedHashMap(retryQueue).also {
                retryQueue.clear()
            }
        }
        GombeCreditLogger.d("Start retry execution, with a total of ${queueToRetry.size} requests")

        // 按照添加顺序执行重试
        queueToRetry.values.sortedBy { it.timestamp }.forEachIndexed { index, request ->
            Handler(Looper.getMainLooper()).postDelayed({
                retryRequest(request)
            }, index * 500L) // 每个请求间隔500ms
        }
    }

    /**
     * 重试单个请求
     */
    private fun retryRequest(request: RetryRequest) {
        request.retryCount++
        GombeCreditLogger.d("Retry request[${request.requestId}], ${request.retryCount} retry, URL: ${request.url}")

        when (request.requestType) {
            "POST" -> {
                val params = request.params as? JSONObject
                if (params != null) {
                    // 使用原有的HttpLoader重试
                    HttpHelper.post(request.url, params, object : IHttpCallback {
                        override fun onRequestSuccess(data: JSONObject) {
                            GombeCreditLogger.d("Retry success: ${request.url}")
                            request.originalCallback.onRequestSuccess(data)
                        }

                        override fun onRequestError(error: JSONObject) {
                            GombeCreditLogger.d("Retry failed: ${request.url}, error: ${error.optString("errorMsg")}")
                            request.originalCallback.onRequestError(error)
                        }

                        override fun onRequestFinish() {
                            availableContext?.hideGombeCreditLoading()
                            request.originalCallback.onRequestFinish()
                        }
                    })
                }
            }
            "UPLOAD" -> {
                val filePath = request.params as? String
                if (!filePath.isNullOrEmpty()) {
                    HttpHelper.upload(filePath, object : IHttpCallback {
                        override fun onRequestSuccess(data: JSONObject) {
                            GombeCreditLogger.d("Retry to upload success: ${request.url}")
                            request.originalCallback.onRequestSuccess(data)
                        }

                        override fun onRequestError(error: JSONObject) {
                            GombeCreditLogger.d("Retry to upload failed: ${request.url}, error: ${error.optString("errorMsg")}")
                            request.originalCallback.onRequestError(error)
                        }

                        override fun onRequestFinish() {
                            availableContext?.hideGombeCreditLoading()
                            request.originalCallback.onRequestFinish()
                        }
                    })
                }
            }
        }
    }

    /**
     * 清空重试队列
     */
    private fun clearRetryQueue() {
        synchronized(retryQueue) {
            val size = retryQueue.size
            retryQueue.clear()
            GombeCreditLogger.d("Clear retry queue, original size: $size")
        }
    }

    /**
     * 获取当前重试队列大小（用于UI显示）
     */
    fun getRetryQueueSize(): Int {
        return synchronized(retryQueue) {
            retryQueue.size
        }
    }

    /**
     * 手动添加请求到重试队列（供外部调用）
     */
    fun addRequestForRetry(request: RetryRequest) {
        addToRetryQueue(request)
    }

    /**
     * 手动触发重试（供外部调用）
     */
    fun triggerRetry() {
        executeRetryQueue()
    }

    /**
     * 重置状态
     */
    fun resetState() {
        isShowingDialog = false
        currentDialog?.dismiss()
        currentDialog = null
    }

    /**
     * 检查是否有注册的 Activity
     */
    fun hasRegisteredActivities(): Boolean {
        synchronized(registeredActivities) {
            registeredActivities.removeAll { it.get() == null }
            return registeredActivities.isNotEmpty()
        }
    }
}